<template>
  <JVxeTable
    ref="tableRef"
    rowNumber
    rowSelection
    dragSort
    keyboardEdit
    sortKey="orderNum"
    addButtonSettings
    :loading="loading"
    :columns="columns"
    :dataSource="dataSource"
    :toolbar="actionButton"
    :maxHeight="tableHeight.normal"
    :disabledRows="{ dbFieldName: ['id', 'has_child'] }"
    tableProps
  />
</template>

<script lang="ts">
  import { defineComponent, ref, getCurrentInstance } from 'vue';
  import { JVxeColumn, JVxeTableInstance, JVxeTypes } from '/@/components/jeecg/JVxeTable/types';
  import { useTableSync } from '../../use/useTableSync';

  const MySQLKeywords = [
    'ADD',
    'ALL',
    'ALTER',
    'ANALYZE',
    'AND',
    'AS',
    'ASC',
    'ASENSITIVE',
    'BEFORE',
    'BETWEEN',
    'BIGINT',
    'BINARY',
    'BLOB',
    'BOTH',
    'BY',
    'CALL',
    'CASCADE',
    'CASE',
    'CHANGE',
    'CHAR',
    'CHARACTER',
    'CHECK',
    'COLLATE',
    'COLUMN',
    'CONDITION',
    'CONNECTION',
    'CONSTRAINT',
    'CONTINUE',
    'CONVERT',
    'CREATE',
    'CROSS',
    'CURRENT_DATE',
    'CURRENT_TIME',
    'CURRENT_TIMESTAMP',
    'CURRENT_USER',
    'CURSOR',
    'DATABASE',
    'DATABASES',
    'DAY_HOUR',
    'DAY_MICROSECOND',
    'DAY_MINUTE',
    'DAY_SECOND',
    'DEC',
    'DECIMAL',
    'DECLARE',
    'DEFAULT',
    'DELAYED',
    'DELETE',
    'DESC',
    'DESCRIBE',
    'DETERMINISTIC',
    'DISTINCT',
    'DISTINCTROW',
    'DIV',
    'DOUBLE',
    'DROP',
    'DUAL',
    'EACH',
    'ELSE',
    'ELSEIF',
    'ENCLOSED',
    'ESCAPED',
    'EXISTS',
    'EXIT',
    'EXPLAIN',
    'FALSE',
    'FETCH',
    'FLOAT',
    'FLOAT4',
    'FLOAT8',
    'FOR',
    'FORCE',
    'FOREIGN',
    'FROM',
    'FULLTEXT',
    'GOTO',
    'GRANT',
    'GROUP',
    'HAVING',
    'HIGH_PRIORITY',
    'HOUR_MICROSECOND',
    'HOUR_MINUTE',
    'HOUR_SECOND',
    'IF',
    'IGNORE',
    'IN',
    'INDEX',
    'INFILE',
    'INNER',
    'INOUT',
    'INSENSITIVE',
    'INSERT',
    'INT',
    'INT1',
    'INT2',
    'INT3',
    'INT4',
    'INT8',
    'INTEGER',
    'INTERVAL',
    'INTO',
    'IS',
    'ITERATE',
    'JOIN',
    'KEY',
    'KEYS',
    'KILL',
    'LABEL',
    'LEADING',
    'LEAVE',
    'LEFT',
    'LIKE',
    'LIMIT',
    'LINEAR',
    'LINES',
    'LOAD',
    'LOCALTIME',
    'LOCALTIMESTAMP',
    'LOCK',
    'LONG',
    'LONGBLOB',
    'LONGTEXT',
    'LOOP',
    'LOW_PRIORITY',
    'MATCH',
    'MEDIUMBLOB',
    'MEDIUMINT',
    'MEDIUMTEXT',
    'MIDDLEINT',
    'MINUTE_MICROSECOND',
    'MINUTE_SECOND',
    'MOD',
    'MODIFIES',
    'NATURAL',
    'NOT',
    'NO_WRITE_TO_BINLOG',
    'NULL',
    'NUMERIC',
    'ON',
    'OPTIMIZE',
    'OPTION',
    'OPTIONALLY',
    'OR',
    'ORDER',
    'OUT',
    'OUTER',
    'OUTFILE',
    'PRECISION',
    'PRIMARY',
    'PROCEDURE',
    'PURGE',
    'RAID0',
    'RANGE',
    'READ',
    'READS',
    'REAL',
    'REFERENCES',
    'REGEXP',
    'RELEASE',
    'RENAME',
    'REPEAT',
    'REPLACE',
    'REQUIRE',
    'RESTRICT',
    'RETURN',
    'REVOKE',
    'RIGHT',
    'RLIKE',
    'SCHEMA',
    'SCHEMAS',
    'SECOND_MICROSECOND',
    'SELECT',
    'SENSITIVE',
    'SEPARATOR',
    'SET',
    'SHOW',
    'SMALLINT',
    'SPATIAL',
    'SPECIFIC',
    'SQL',
    'SQLEXCEPTION',
    'SQLSTATE',
    'SQLWARNING',
    'SQL_BIG_RESULT',
    'SQL_CALC_FOUND_ROWS',
    'SQL_SMALL_RESULT',
    'SSL',
    'STARTING',
    'STRAIGHT_JOIN',
    'TABLE',
    'TERMINATED',
    'THEN',
    'TINYBLOB',
    'TINYINT',
    'TINYTEXT',
    'TO',
    'TRAILING',
    'TRIGGER',
    'TRUE',
    'UNDO',
    'UNION',
    'UNIQUE',
    'UNLOCK',
    'UNSIGNED',
    'UPDATE',
    'USAGE',
    'USE',
    'USING',
    'UTC_DATE',
    'UTC_TIME',
    'UTC_TIMESTAMP',
    'VALUES',
    'VARBINARY',
    'VARCHAR',
    'VARCHARACTER',
    'VARYING',
    'WHEN',
    'WHERE',
    'WHILE',
    'WITH',
    'WRITE',
    'X509',
    'XOR',
    'YEAR_MONTH',
    'ZEROFILL',
  ];

  export default defineComponent({
    name: 'DBAttributeTable',
    props: {
      actionButton: { type: Boolean, default: true },
    },
    emits: ['added', 'removed', 'inserted', 'dragged', 'syncDbType'],
    setup(props, { emit }) {
      const instance = getCurrentInstance();
      const addBatching = ref(false);
      const columns = ref([
        {
          title: '字段名称',
          key: 'dbFieldName',
          width: 140,
          type: JVxeTypes.input,
          defaultValue: '',
          placeholder: '请输入${title}',
          validateRules: [
            { required: true, message: '${title}不能为空' },
            {
              pattern: /^[a-zA-Z]{1}(?!_)[a-zA-Z0-9_\\$]+$/,
              message: '命名规则：只能由字母、数字、下划线、$符号组成；必须以字母开头；不能以单个字母加下滑线开头',
            },
            { unique: true, message: '${title}不能重复' },
            {
              handler({ cellValue }, callback) {
                if (MySQLKeywords.includes(cellValue.toUpperCase())) {
                  callback(false, cellValue + '是关键字，不能作为字段名称使用！');
                } else {
                  callback(true);
                }
              },
            },
            { handler: validateExistIndex },
          ],
          disabled: !props.actionButton,
        },
        {
          title: '字段备注',
          key: 'dbFieldTxt',
          width: 140,
          type: JVxeTypes.input,
          defaultValue: '',
          placeholder: '请输入${title}',
          validateRules: [{ required: true, message: '${title}不能为空' }],
        },
        {
          title: '字段长度',
          key: 'dbLength',
          width: 120,
          type: JVxeTypes.inputNumber,
          defaultValue: 32,
          placeholder: '请输入${title}',
          validateRules: [{ required: true, message: '${title}不能为空' }],
          disabled: !props.actionButton,
        },
        {
          title: '小数点',
          key: 'dbPointLength',
          width: 100,
          type: JVxeTypes.inputNumber,
          defaultValue: 0,
          placeholder: '请输入${title}',
          validateRules: [{ required: true, message: '${title}不能为空' }],
          disabled: !props.actionButton,
        },
        {
          title: '默认值',
          key: 'dbDefaultVal',
          width: 140,
          type: JVxeTypes.input,
          defaultValue: '',
          disabled: !props.actionButton,
        },
        {
          title: '字段类型',
          key: 'dbType',
          width: 140,
          type: JVxeTypes.select,
          options: [
            { title: 'String', value: 'string' },
            { title: 'Integer', value: 'int' },
            { title: 'Double', value: 'double' },
            { title: 'Date', value: 'Date' },
            { title: 'Datetime', value: 'Datetime' },
            { title: 'BigDecimal', value: 'BigDecimal' },
            { title: 'Text', value: 'Text' },
            { title: 'Blob', value: 'Blob' },
          ],
          defaultValue: 'string',
          placeholder: '请选择${title}',
          disabled: !props.actionButton,
          validateRules: [{ required: true, message: '请选择${title}' }],
        },
        {
          title: '主键',
          key: 'dbIsKey',
          width: 80,
          type: JVxeTypes.checkbox,
          align: 'center',
          customValue: ['1', '0'],
          defaultChecked: false,
          disabled: !props.actionButton,
        },
        {
          title: '允许空值',
          key: 'dbIsNull',
          width: 80,
          type: JVxeTypes.checkbox,
          customValue: ['1', '0'],
          defaultChecked: true,
          disabled: !props.actionButton,
        },
        {
          title: '同步数据库',
          key: 'dbIsPersist',
          minWidth: 80,
          type: JVxeTypes.checkbox,
          customValue: ['1', '0'],
          defaultChecked: true,
          disabled: !props.actionButton,
        },
        { title: 'orderNum', key: 'orderNum', type: JVxeTypes.hidden },
      ]);
      let removeIds = [];
      const setup = useTableSync(columns);
      const { tableRef, loading, dataSource, tableHeight, tableProps, setDataSource, validateData } = setup;
      function handleAdded() {
        emit('added', instance);
      }
      function handleRemoved(event) {
        removeIds = removeIds.concat(event.deleteRows.map((r) => r.id));
        emit('removed', { ...event, removeIds, target: instance });
      }
      function handleDragged(event) {
        emit('dragged', {
          oldIndex: event.oldIndex,
          newIndex: event.newIndex,
          target: instance,
        });
      }
      function handleInserted(event) {
        emit('inserted', { ...event, target: instance });
      }
      function getRemoveIds() {
        return removeIds;
      }
      function handleValueChange(event) {
        let { type, row, col, value, target } = event;
        if (type === JVxeTypes.select && col.key === 'dbType') {
          if (value === 'Date' || value === 'Datetime') {
            emit('syncDbType', { row, value, target: instance });
          }
          if (value === 'Blob' || value === 'Text' || value === 'Date') {
            target.setValues([{ rowKey: row.id, values: { dbLength: '0' } }]);
          } else if (value === 'int' || value === 'double' || value === 'BigDecimal') {
            target.setValues([{ rowKey: row.id, values: { dbLength: '10' } }]);
          } else if (row['dbLength'] === '0') {
            target.setValues([{ rowKey: row.id, values: { dbLength: '32' } }]);
          }
        }
      }
      function tableAddLine(newLine) {
        tableRef.value.pushRows(newLine);
        if (!addBatching.value) {
          emit('added', instance);
        }
      }
      function tableDeleteLines(ids) {
        return tableRef.value.removeRowsById(ids);
      }
      function addBatchBegin() {
        addBatching.value = true;
        loading.value = true;
      }
      function addBatchEnd() {
        addBatching.value = false;
        loading.value = false;
        emit('added', instance);
      }
      function validateExistIndex({ cellValue, row }, callback) {
        const { tables } = setup;
        if (tables) {
          let dataSource2 = tables.dbTable.value.tableRef.dataSource;
          let temp = dataSource2.filter((item) => item.id === row.id);
          if (!temp || temp.length <= 0) {
            callback(true);
          }
          let dbFieldName = temp[0]['dbFieldName'];
          if (dbFieldName == cellValue) {
            callback(true);
          }
          let arr = tables.idxTable.value.tableRef.getTableData();
          for (let item of arr) {
            let indexField = item.indexField;
            let indexFieldArray = indexField.split(',');
            if (indexFieldArray.indexOf(dbFieldName) >= 0) {
              callback(false, '当前字段存在索引配置，请先删除索引再修改字段');
            }
          }
        }
        callback(true);
      }
      return {
        tableRef,
        loading,
        columns,
        dataSource,
        setDataSource,
        addBatchBegin,
        addBatchEnd,
        tableAddLine,
        tableHeight,
        tableProps,
        tableDeleteLines,
        handleAdded,
        handleRemoved,
        handleDragged,
        handleInserted,
        handleValueChange,
        validateData,
        getRemoveIds,
        validateExistIndex,
      };
    },
  });
</script>
